package com.tsing.wms.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tsing.wms.config.RedisManager;
import com.tsing.wms.constant.AuthConsts;
import com.tsing.wms.entity.*;
import com.tsing.wms.exception.CommonException;
import com.tsing.wms.exception.ServerException;
import com.tsing.wms.mapper.*;
import com.tsing.wms.service.ISupplierService;
import com.tsing.wms.util.GetLoginUserUtil;
import com.tsing.wms.vo.PageResultVO;
import com.tsing.wms.vo.req.IdReqVO;
import com.tsing.wms.vo.req.IdsReqVO;
import com.tsing.wms.vo.req.SupplierPageReqVO;
import com.tsing.wms.vo.req.SupplierReqVO;
import com.tsing.wms.vo.resp.IdAndNameRespVO;
import com.tsing.wms.vo.resp.SupplierRespVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;

/**
 * <p>
 * 供应商表 服务实现类
 * </p>
 *
 * @author TheTsing
 * @since 2022-04-13
 */
@Service
public class SupplierServiceImpl extends ServiceImpl<SupplierMapper, SupplierEntity> implements ISupplierService {

    @Autowired
    private RedisManager redisManager;

    @Resource
    private UserMapper userMapper;

    @Resource
    private RegionMapper regionMapper;

    @Override
    public List<IdAndNameRespVO> userList() {
        List<UserEntity> userEntities = userMapper.selectList(null);
        HashMap<String, String> fieldMapping = new HashMap<>(4);
        fieldMapping.put("username", "name");
        return BeanUtil.copyToList(userEntities, IdAndNameRespVO.class, new CopyOptions().setFieldMapping(fieldMapping));
    }

    @Override
    public List<IdAndNameRespVO> regionList() {
        List<RegionEntity> regionEntities = regionMapper.selectList(null);
        HashMap<String, String> fieldMapping = new HashMap<>(4);
        fieldMapping.put("address", "name");
        return BeanUtil.copyToList(regionEntities, IdAndNameRespVO.class, new CopyOptions().setFieldMapping(fieldMapping));
    }

    @Override
    public void addSupplier(SupplierReqVO reqVO, HttpServletRequest request) {
        if (GetLoginUserUtil.getLoginUserInfo(request.getHeader(AuthConsts.AUTHENTICATION_HEAD), redisManager).getIdentity() != 1) {
            throw new ServerException(CommonException.Proxy.AUTHORIZATION_EXCEPTION);
        }
        if (ObjectUtil.isNotNull(new LambdaQueryChainWrapper<>(baseMapper)
                .select(SupplierEntity::getId)
                .eq(SupplierEntity::getName, reqVO.getName())
                .eq(SupplierEntity::getRegionId, reqVO.getRegionId())
                .one())) {
            throw new ServerException(CommonException.Proxy.SUPPLIER_IS_NOTNULL);
        }
        SupplierEntity supplierEntity = new SupplierEntity();
        BeanUtil.copyProperties(reqVO, supplierEntity);
        baseMapper.insert(supplierEntity);
    }

    @Resource
    private GoodsMapper goodsMapper;
    @Resource
    private OrderMapper orderMapper;

    @Override
    public void deleteSupplier(IdsReqVO reqVO, HttpServletRequest request) {
        if (GetLoginUserUtil.getLoginUserInfo(request.getHeader(AuthConsts.AUTHENTICATION_HEAD), redisManager).getIdentity() != 1) {
            throw new ServerException(CommonException.Proxy.AUTHORIZATION_EXCEPTION);
        }
        for (String id : reqVO.getIds()) {
            if (0 != new LambdaQueryChainWrapper<>(goodsMapper)
                    .select(GoodsEntity::getId)
                    .eq(GoodsEntity::getSupplierId, id)
                    .count()) {
                throw new ServerException(CommonException.Proxy.SUPPLIER_RELEVANCE_GOODS);
            }
            if (0 != new LambdaQueryChainWrapper<>(orderMapper)
                    .select(OrderEntity::getId)
                    .eq(OrderEntity::getSupplierId, id)
                    .count()) {
                throw new ServerException(CommonException.Proxy.SUPPLIER_RELEVANCE_ORDER);
            }
        }
        baseMapper.deleteBatchIds(reqVO.getIds());
    }

    @Override
    public SupplierRespVO getSupplier(IdReqVO reqVO) {
        SupplierEntity supplierEntity = baseMapper.selectById(reqVO.getId());
        SupplierRespVO supplierRespVO = new SupplierRespVO();
        BeanUtil.copyProperties(supplierEntity, supplierRespVO);
        supplierRespVO.setUsername(new LambdaQueryChainWrapper<>(userMapper)
                .select(UserEntity::getUsername)
                .eq(UserEntity::getId, supplierRespVO.getUserId())
                .one()
                .getUsername());
        supplierRespVO.setRegionName(new LambdaQueryChainWrapper<>(regionMapper)
                .select(RegionEntity::getAddress)
                .eq(RegionEntity::getId, supplierRespVO.getRegionId())
                .one()
                .getAddress());
        return supplierRespVO;
    }

    @Override
    public void updateSupplier(SupplierReqVO reqVO, HttpServletRequest request) {
        if (GetLoginUserUtil.getLoginUserInfo(request.getHeader(AuthConsts.AUTHENTICATION_HEAD), redisManager).getIdentity() != 1) {
            throw new ServerException(CommonException.Proxy.AUTHORIZATION_EXCEPTION);
        }
        if (StrUtil.isNotBlank(reqVO.getName())) {
            if (StrUtil.isNotBlank(reqVO.getRegionId())) {
                if (ObjectUtil.isNotNull(new LambdaQueryChainWrapper<>(baseMapper)
                        .select(SupplierEntity::getId)
                        .eq(SupplierEntity::getName, reqVO.getName())
                        .eq(SupplierEntity::getRegionId, reqVO.getRegionId())
                        .ne(SupplierEntity::getId, reqVO.getId())
                        .one())) {
                    throw new ServerException(CommonException.Proxy.SUPPLIER_IS_NOTNULL);
                }
            } else {
                if (ObjectUtil.isNotNull(new LambdaQueryChainWrapper<>(baseMapper)
                        .select(SupplierEntity::getId)
                        .eq(SupplierEntity::getName, reqVO.getName())
                        .eq(SupplierEntity::getRegionId, baseMapper.selectById(reqVO.getId()).getRegionId())
                        .ne(SupplierEntity::getId, reqVO.getId())
                        .one())) {
                    throw new ServerException(CommonException.Proxy.SUPPLIER_IS_NOTNULL);
                }
            }
        }
        SupplierEntity supplierEntity = new SupplierEntity();
        BeanUtil.copyProperties(reqVO, supplierEntity);
        baseMapper.updateById(supplierEntity);
    }

    @Override
    public PageResultVO<SupplierRespVO> supplierPage(SupplierPageReqVO reqVO) {
        IPage<SupplierEntity> page = new Page<>(reqVO.getPageNum(), reqVO.getPageSize());
        new LambdaQueryChainWrapper<>(baseMapper)
                .like(StrUtil.isNotBlank(reqVO.getName()), SupplierEntity::getName, reqVO.getName())
                .page(page);
        List<SupplierRespVO> supplierRespVOs = BeanUtil.copyToList(page.getRecords(), SupplierRespVO.class);
        supplierRespVOs.forEach(item -> {
            UserEntity userEntity = new LambdaQueryChainWrapper<>(userMapper)
                    .select(UserEntity::getUsername, UserEntity::getPhone)
                    .eq(UserEntity::getId, item.getUserId())
                    .one();
            item.setUsername(userEntity.getUsername());
            item.setPhone(userEntity.getPhone());
            item.setRegionName(new LambdaQueryChainWrapper<>(regionMapper)
                    .select(RegionEntity::getAddress)
                    .eq(RegionEntity::getId, item.getRegionId())
                    .one()
                    .getAddress());
            item.setGoodsCount(new LambdaQueryChainWrapper<>(goodsMapper)
                    .select(GoodsEntity::getId)
                    .eq(GoodsEntity::getSupplierId, item.getId())
                    .count());
        });
        return new PageResultVO<>(page, supplierRespVOs);
    }

}
